﻿using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 狀態機
/// </summary>
public class StateMachine<T>
{
    /// <summary>
    /// 狀態列表
    /// </summary>
    private List<StateBase<T>> stateList;

    /// <summary>
    /// 狀態所有者
    /// </summary>
    private T Owner;

    /// <summary>
    /// 當前的狀態
    /// </summary>
    private StateBase<T> CurrentState;

    /// <summary>
    /// 上一個狀態
    /// </summary>
    private StateBase<T> PreviousState;

    /// <summary>
    /// 緊急狀態（可先於當前狀態執行）
    /// </summary>
    private StateBase<T> UrgentState;

    public StateMachine(T owner)
    {
        Owner = owner;
        stateList = new List<StateBase<T>>();
    }

    #region 增添狀態
    /// <summary>
    /// 添加狀態
    /// </summary>
    public void AddState(StateBase<T> state)
    {
        if (GetStateInList(state.StateName) == null)
        {
            stateList.Add(state);
        }
        else
        {
            Debug.LogWarning("狀態已存在：" + state.StateName);
        }
    }
    #endregion

    #region 刪除狀態
    /// <summary>
    ///刪除狀態（通過名稱）
    /// </summary>
    public void RemoveState(string stateName)
    {
        StateBase<T> state = GetStateInList(stateName);
        if (state != null)
        {
            stateList.Remove(state);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + stateName);
        }
    }

    /// <summary>
    /// 刪除狀態（通過引用）
    /// </summary>
    /// <param name="state"></param>
    public void RemoveState(StateBase<T> state)
    {
        if (state != null && stateList.Contains(state))
        {
            stateList.Remove(state);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + state.StateName);
        }
    }
    #endregion

    #region 修改狀態
    /// <summary>
    /// 設定當前狀態
    /// </summary>
    public void SetCurrentState(StateBase<T> state)
    {
        CurrentState = state;
    }

    /// <summary>
    /// 設定當前狀態
    /// </summary>
    public void SetCurrentState(string stateName)
    {
        if (GetStateInList(stateName) != null)
        {
            CurrentState = GetStateInList(stateName);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + stateName);
        }
    }

    /// <summary>
    /// 設定上一個狀態
    /// </summary>
    public void SetPreviousState(StateBase<T> state)
    {
        PreviousState = state;
    }

    /// <summary>
    /// 設定上一個狀態
    /// </summary>
    public void SetPreviousState(string stateName)
    {
        if (GetStateInList(stateName) != null)
        {
            PreviousState = GetStateInList(stateName);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + stateName);
        }
    }

    /// <summary>
    /// 設定緊急狀態
    /// </summary>
    public void SetUrgentState(StateBase<T> state)
    {
        UrgentState = state;
    }

    /// <summary>
    /// 設定緊急狀態
    /// </summary>
    public void SetUrgentState(string stateName)
    {
        if (GetStateInList(stateName) != null)
        {
            UrgentState = GetStateInList(stateName);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + stateName);
        }
    }

    /// <summary>
    /// 改變狀態
    /// </summary>
    public void ChangeState(StateBase<T> state)
    {
        PreviousState = CurrentState;
        if (CurrentState != null)
        {
            CurrentState.StateExit(Owner);
        }
        CurrentState = state;
        CurrentState.StateEnter(Owner);
    }

    /// <summary>
    /// 改變狀態
    /// </summary>
    /// <param name="stateName">狀態名</param>
    public void ChangeState(string stateName)
    {
        if (GetStateInList(stateName) != null)
        {
            PreviousState = CurrentState;
            if (CurrentState != null)
            {
                CurrentState.StateExit(Owner);
            }
            CurrentState = GetStateInList(stateName);
            CurrentState.StateEnter(Owner);
        }
        else
        {
            Debug.LogWarning("狀態不存在：" + stateName);
        }
    }

    /// <summary>
    /// 回到之前的狀態
    /// </summary>
    public void RevertToPreviousState()
    {
        ChangeState(PreviousState);
    }
    #endregion

    #region 查找狀態
    /// <summary>
    /// 通過狀態名字獲取列表中狀態
    /// </summary>
    public StateBase<T> GetStateInList(string stateName)
    {
        foreach (var item in stateList)
        {
            if (item.StateName == stateName)
            {
                return item;
            }
        }
        return null;
    }

    /// <summary>
    /// 獲取當前狀態
    /// </summary>
    public StateBase<T> GetCurrentState()
    {
        return CurrentState;
    }

    /// <summary>
    /// 獲取上一個狀態
    /// </summary>
    public StateBase<T> GetPreviousState()
    {
        return PreviousState;
    }

    /// <summary>
    /// 獲取緊急狀態
    /// </summary>
    public StateBase<T> GetUrgentState()
    {
        return UrgentState;
    }

    /// <summary>
    /// 是否處於某狀態
    /// </summary>
    public bool IsState(StateBase<T> state)
    {
        return state == CurrentState;
    }

    public bool IsState(string stateName)
    {
        StateBase<T> state = GetStateInList(stateName);
        return state == CurrentState;
    }

    #endregion


    /// <summary>
    ///狀態機更新
    /// </summary>
    public void Update()
    {
        if (UrgentState != null)
        {
            UrgentState.Update(Owner);
        }

        if (CurrentState != null)
        {
            CurrentState.Update(Owner);
        }
    }

}

